home *** CD-ROM | disk | FTP | other *** search
- /********************************************/
- /* Copyright 1997 MetaCard Corporation */
- /* All Rights Reserved */
- /********************************************/
- /*
- * Support routines for MetaCard external commands and functions
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <values.h>
- #include <fcntl.h>
- #ifdef SELECT
- #ifndef LINUX
- /* some systems don't have select.h and/or stream.h. If yours doesn't
- delete the offending #include */
- #include <sys/select.h>
- #include <sys/stream.h>
- #endif
- #else
- #include <poll.h>
- #endif
- #include <X11/Xlib.h>
- #include <X11/Xos.h>
- #include <X11/Xatom.h>
- #include <X11/Intrinsic.h>
- #include "XCmdGlue.h"
- #include "XCmdName.h"
-
- #define XATOMSIZE 16
- #define XINTSTRSIZE 16
- #define XMAXPACK 65535
-
- extern int wait();
-
- Display *MCdpy;
- Window MCwin = 0;
- Widget MCwidget;
- int MCpid;
-
- static char *XCAtomNames[MC_NUM_ATOMS] = {
- MC_ID_STRING,
- MC_ABORT_STRING,
- MC_REGISTER_STRING,
- MC_CARD_MESSAGE_STRING,
- MC_MC_MESSAGE_STRING,
- MC_EVAL_EXPRESSION_STRING,
- MC_GET_GLOBAL_STRING,
- MC_SET_GLOBAL_STRING,
- MC_GET_FIELD_BY_NAME_STRING,
- MC_GET_FIELD_BY_NUMBER_STRING,
- MC_GET_FIELD_BY_ID_STRING,
- MC_SET_FIELD_BY_NAME_STRING,
- MC_SET_FIELD_BY_NUMBER_STRING,
- MC_SET_FIELD_BY_ID_STRING,
- MC_SHOW_IMAGE_BY_NAME_STRING,
- MC_SHOW_IMAGE_BY_NUMBER_STRING,
- MC_SHOW_IMAGE_BY_ID_STRING,
- MC_GET_VARIABLE_STRING,
- MC_SET_VARIABLE_STRING,
- MC_GET_VARIABLE_EX_STRING,
- MC_SET_VARIABLE_EX_STRING
- ,
- MC_GET_ARRAY,
- MC_SET_ARRAY
- };
-
- static Atom XCAtoms[MC_NUM_ATOMS];
- static Atom mcatom;
- static Atom idatom = None;
-
- static char *XTretmess;
- static int XTretval;
-
- #ifdef __STDC__
- static void propevent(Widget w, XtPointer client_data,
- XEvent *event, Boolean *dispatch)
- #else
- static void propevent(w, client_data, event, dispatch)
- Widget w;
- XtPointer client_data;
- XEvent *event;
- Boolean *dispatch;
- #endif
- {
- XPropertyEvent *pevent = (XPropertyEvent *)event;
- if (pevent->state != PropertyNewValue)
- return;
- if (pevent->atom == (Atom)client_data) {
- Atom type;
- int format;
- unsigned long nitems, extra;
- unsigned char *uprop;
- char *prop;
- char *sptr;
- XGetWindowProperty(MCdpy, MCwin, pevent->atom, 0,
- XMAXPACK, False, XA_STRING, &type, &format,
- &nitems, &extra, &uprop);
- prop = (char *)uprop;
- if (atol(prop) != (long)idatom) {
- XFree(prop);
- *dispatch = True;
- return;
- }
- sptr = &prop[strlen(prop) + 1];
- sptr += strlen(sptr) + 1;
- XTretval = atoi(sptr);
- sptr += strlen(sptr) + 1;
- XTretmess = malloc(strlen(sptr) + 1);
- strcpy(XTretmess, sptr);
- XFree(prop);
- *dispatch = False;
- }
- else
- *dispatch = True;
- }
-
- #ifdef __STDC__
- static char *event_wait(Atom reply, int *retval)
- #else
- static char *event_wait(reply, retval)
- Atom reply;
- int *retval;
- #endif
- {
- XEvent event;
- XtAppContext context;
-
- context = XtWidgetToApplicationContext(MCwidget);
- XFlush(MCdpy);
- XTretmess = NULL;
- while (XTretmess == NULL) {
- XtAppNextEvent(context, &event);
- XtDispatchEvent(&event);
- }
- *retval = XTretval;
- return XTretmess;
- }
-
- #ifdef __STDC__
- static char *send_message(Atom atom, const char *arg1, const char *arg2,
- const char *arg3, Bool pass, Bool error, int *reply)
- #else
- static char *send_message(atom, arg1, arg2, arg3, pass, error, reply)
- Atom atom;
- char *arg1;
- char *arg2;
- char *arg3;
- Bool pass;
- Bool error;
- int *reply;
- #endif
- {
- int i = 0;
- int length = XATOMSIZE * 2 + strlen(arg1) + 7;
- char *send;
- if (arg2 != NULL)
- length += strlen(arg2);
- if (arg3 != NULL)
- length += strlen(arg3);
- send = malloc(length);
- sprintf(&send[i], "%d", mcatom);
- i += strlen(&send[i]) + 1;
- sprintf(&send[i], "%d", idatom);
- i += strlen(&send[i]) + 1;
- sprintf(&send[i], "%d", (int)(pass != 0));
- i += strlen(&send[i]) + 1;
- sprintf(&send[i], "%d", (int)(error != 0));
- i += strlen(&send[i]) + 1;
- sprintf(&send[i], "%s", arg1);
- if (arg2 != NULL) {
- i += strlen(&send[i]) + 1;
- sprintf(&send[i], "%s", arg2);
- }
- if (arg3 != NULL) {
- i += strlen(&send[i]) + 1;
- sprintf(&send[i], "%s", arg3);
- }
- i += strlen(&send[i]) + 1;
- XtAddEventHandler(MCwidget, PropertyChangeMask, FALSE,
- propevent, (XtPointer)atom);
- XChangeProperty(MCdpy, MCwin, atom, XA_STRING, 8,
- PropModeReplace, (unsigned char *)send, i);
- free(send);
- if (reply != NULL)
- send = event_wait(atom, reply);
- else
- send = NULL;
- XtRemoveEventHandler(MCwidget, PropertyChangeMask, FALSE,
- propevent, (XtPointer)atom);
- return send;
- }
-
- #ifdef __STDC__
- void mc_xtinit(Widget ps, char *stack)
- #else
- void mc_xtinit(ps, stack)
- Widget ps;
- char *stack;
- #endif
- {
- MCwidget = ps;
- MCwin = XtWindow(ps);
- MCdpy = XtDisplay(ps);
- XSync(MCdpy, False);
- fcntl(ConnectionNumber(MCdpy), F_SETFD, 1);
- if ((MCpid = fork()) == 0) {
- char wbuf[XINTSTRSIZE];
- sprintf(wbuf, "%d", MCwin);
- execlp("mc", "mc", "-w", wbuf, "-d", DisplayString(MCdpy), stack, NULL);
- fprintf(stderr, "startup of mc with stack %s failed\n", stack);
- exit(-1);
- }
- mcatom = XInternAtom(MCdpy, XCAtomNames[MC_ID], False);
- idatom = XInternAtom(MCdpy, "XtApplication", False);
- }
-
- void mc_xtclose()
- {
- int status;
- XFlush(MCdpy);
- waitpid(MCpid, &status, 0);
- }
-
- static char *callback(int id, const char *arg1, const char *arg2,
- const char *arg3, int *retval)
- {
- if (XCAtoms[id] == None)
- XCAtoms[id] = XInternAtom(MCdpy, XCAtomNames[id], False);
- return send_message(XCAtoms[id], arg1, arg2, arg3, False, False, retval);
- }
-
- static char *getstatus()
- {
- Atom type;
- int format;
- unsigned long nitems, extra;
- unsigned char *uprop;
- char *newprop;
- Atom statatom = XInternAtom(MCdpy, MC_GET_MC_STATUS_STRING, False);
- XGetWindowProperty(MCdpy, MCwin, statatom, 0,
- XMAXPACK, False, XA_STRING, &type,
- &format, &nitems, &extra, &uprop);
- if (type == None)
- return istrdup("startup");
- newprop = (char *)uprop;
- newprop = istrdup(newprop);
- XFree(uprop);
- return newprop;
- }
-
- #include "XCmdFunc.c"
-